import { store, setBaseItem, setUserItem } from '@s';
import { authLogout, infoUserProfile, homeRouters } from '@a/public';

// 获取用户信息
export function GetInfo() {
	return new Promise((resolve, reject) => {
		infoUserProfile()
			.then((res) => {
				if (res?.data) {
					const {
						user: { id, userName, nickName, deptId, avatar },
						roles,
						perms
					} = res.data;
					store.dispatch(
						setBaseItem({
							userInfo: { userId: id, userName, nickName, deptId },
							avatar,
							permissions: perms,
							roles: roles.length ? roles : ['ROLE_DEFAULT']
						})
					);
				}
				resolve(res);
			})
			.catch((error) => {
				reject(error);
			});
	});
}
// 退出系统
export function LogOut() {
	return new Promise((resolve, reject) => {
		authLogout()
			.then(() => {
				LogOutSET();
				resolve();
			})
			.catch((error) => {
				reject(error);
			});
	});
}
// 清空相关数据
export function LogOutSET() {
	store.dispatch(
		setBaseItem({
			token: '',
			roles: [],
			userInfo: {},
			avatar: '',
			permissions: [],
			tags: [],
			activeTagId: ''
		})
	);
	store.dispatch(
		setUserItem({
			menuList: [],
			Routes: [],
			queryRoutes: false
		})
	);
}

/*****************************************************************************动态权限路由***************************************/
import { find } from '@u/tree';
// 默认布局Layout、ParentView
import Layout from '@/extension/layout';
import ParentView from '@/extension/ParentView';
/*
 * 处理解决import动态加载组件 打包部署为空的问题
 * **为通配符,vite不支持require导入方式,故用import.meta.glob(vite动态导入)
 * import.meta.glob
 * 该方法匹配到的文件默认是懒加载，通过动态导入实现，构建时会分离独立的 chunk，是异步导入，返回的是 Promise
 * import.meta.globEager
 * 该方法是直接导入所有模块，并且是同步导入，返回结果直接通过 for...in循环就可以操作
 */
const modules = import.meta.glob('../views/**/*.jsx');
// 生成对应权限的路由
export function GenerateRoutes() {
	return new Promise((resolve) => {
		// 向后端请求路由数据
		homeRouters().then((res) => {
			if (res?.data?.length) {
				const { menuList, Routes, BreadcrumbList } = filterAsyncRouter(clone(res.data));

				store.dispatch(
					setUserItem({
						menuList,
						Routes: [
							{
								path: '/',
								redirect: find(menuList, true, (item) => !item.children).path
							},
							...Routes,
							{
								path: '*',
								redirect: '/404'
							}
						],
						BreadcrumbList,
						queryRoutes: true
					})
				);
				resolve();
			} else {
				Modal.confirm({
					title: '系统提示',
					content: '该角色用户暂无可视页面，请管理员分配角色权限！',
					centered: true,
					onOk() {
						LogOut();
						window.location.reload();
					}
				});
			}
		});
	});
}
// 遍历后台传来的路由字符串，转换为组件对象  动态添加路由
function filterAsyncRouter(data) {
	const layoutData = Object.create(null),
		RoutesData = Object.create(null),
		MenusData = Object.create(null);

	// 数据转换为对象
	data.forEach((item) => {
		/**
		 * id 数据ID
		 * parentId 父类ID
		 * component .vue文件路径
		 * layoutPath 布局路径 layoutPath == undefined为默认布局，layoutPath == 'ParentView'全屏布局，modules[`../views/${layoutPath}.vue`]自定义页面布局
		 * icon 菜单图标
		 * menuName 菜单名称
		 * menuType 菜单类型  M——目录、C——菜单
		 * path 菜单路由
		 * visible 是否显示
		 * isCache 是否缓存
		 * orderNum 排序
		 */
		const { id, parentId, layoutPath, icon, menuName, menuType, path, visible, orderNum } = item;
		const { component } = item;
		let element = null;

		/*****************************************************布局数据生成****************************/
		element = modules[`../views/${component}.jsx`];
		if (menuType == 'M' && !element) {
			element = parentId == '0' ? <Layout /> : <ParentView />;
		}

		/*****************************************************路由数据生成****************************/
		const Path = parentId == '0' ? (/^(\/)/.test(path) ? path : `/${path}`) : path;
		RoutesData[id] = {
			parentId,
			id,
			icon,
			label: menuName,
			name: component,
			element,
			hidden: visible == 1,
			path: Path,
			orderNum
		};

		// 无目录菜单
		if (parentId == '0' && menuType == 'C') {
			// 布局 layoutPath为默认布局，layoutPath == 'ParentView'全屏布局，modules[`../views/${layoutPath}.jsx`]自定义页面布局
			const layout = !layoutPath ? <Layout /> : layoutPath == 'ParentView' ? <ParentView /> : modules[`../views/${layoutPath}.jsx`],
				parentName = !layoutPath ? '/Layout' : layoutPath == 'ParentView' ? '/ParentView' : `/${layoutPath}`;

			// 添加布局页面
			if (!layoutData[parentName]) {
				layoutData[parentName] = {
					name: parentName,
					path: '/',
					element: layout,
					layout: true
				};
			}

			RoutesData[id].parentName = parentName;
		}

		/*****************************************************菜单数据生成****************************/
		if (visible !== 1) MenusData[id] = cloneDeep(RoutesData[id]);
	});

	// 组成路由树形结构
	const Routes = [];
	for (const key in RoutesData) {
		const item = RoutesData[key];
		if (item.parentId == '0') {
			if (item.parentName) {
				const data = Routes.find((item2) => item2.name == item.parentName);
				if (data) {
					data.children.push(item);
				} else {
					layoutData[item.parentName].children = [item];
					Routes.push(layoutData[item.parentName]);
				}
			} else {
				Routes.push(item);
			}
		} else {
			const parent = RoutesData[item.parentId];
			if (parent) {
				if (!parent.children) parent.children = [];
				parent.children.push(item);
			}
		}
	}

	// 组成菜单树形结构
	const Menus = [];
	for (const key in MenusData) {
		const item = MenusData[key];
		if (item.parentId == '0') {
			Menus.push(item);
			Menus.sort((a, b) => {
				return a.orderNum - b.orderNum;
			});
		} else {
			const parent = MenusData[item.parentId];
			if (parent) {
				if (!parent.children) parent.children = [];
				parent.children.push(item);
				parent.children.sort((a, b) => {
					return a.orderNum - b.orderNum;
				});
			}
		}
	}

	// 菜单path拼接
	function MenusFn(data, parentPath) {
		return data.map((item) => {
			if (item.parentId != 0) item.path = parentPath ? `${parentPath}/${item.path}` : item.path;
			if (item.children?.length) MenusFn(item.children, item.path);
			return item;
		});
	}
	const finallyMenus = MenusFn(cloneDeep(Menus));

	// Breadcrumb 面包屑数据处理
	const BreadcrumbList = {};
	function BreadcrumbFn(data, list = []) {
		data.map((item) => {
			if (item.children?.length) {
				const data = [...list, { title: item.label, path: find(item.children, true, (item2) => !item2.children).path }];
				BreadcrumbFn(item.children, data);
			} else {
				const data = [...list, { title: item.label, path: item.path }];
				BreadcrumbList[item.path] = data;
			}
		});
	}
	BreadcrumbFn(finallyMenus);

	return { menuList: finallyMenus, Routes: MenusFn(cloneDeep(Routes)), BreadcrumbList };
}
